package com.kuang.pool;

import java.util.concurrent.*;

/**
 * Author: Zhang Dongwei
 * Date: 2022/3/13 19:12
 * Executors 工具类，3大方法
 * 使用了线程池之后，使用线程池来创建线程
 * 拒绝策略：
 * 1.  new ThreadPoolExecutor.AbortPolicy());   银行满了，还有人进来，不处理这个人，抛出异常
 * 2.  new ThreadPoolExecutor.CallerRunsPolicy()); // 哪来的回去哪里
 * 3.  new ThreadPoolExecutor.DiscardPolicy()); // 队列满了，丢掉任务，不会抛出异常
 * 4.  new ThreadPoolExecutor.DiscardOldestPolicy()); // 队列满了，尝试去和最早的竞争，如果成功就运行，失败就丢弃，也不会抛出异常
 */
public class Demo02 {
    public static void main(String[] args) {
        // 自定义线程池，工作中只会使用这种方式创建线程池：ThreadPoolExecutor

        // 最大线程到底如何定义
        // 1. CPU密集型， CPU几核就是几，可以保持CPU效率最高  =》Runtime.getRuntime().availableProcessors(),
        // 2. IO密集型 ：要大于判断你程序中十分消耗IO的进程
        // 程序  15个大型任务， io十分占用资源！

        System.out.println(Runtime.getRuntime().availableProcessors()); // 查看CPU有几核

        ExecutorService threadPool = new ThreadPoolExecutor(2,
                Runtime.getRuntime().availableProcessors(),
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy()); // 队列满了，尝试去和最早的竞争，如果成功就运行，失败就丢弃，也不会抛出异常
        try {
            // 最大承载：Deque + max
            // 超过RejectedExecutionException
            for (int i = 1; i <= 9; i++) {
                // 使用了线程池之后，使用线程池来创建线程
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"=>OK");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 线程池用完，程序结束，关闭线程池
            threadPool.shutdown();
        }
    }
}
